package com.huicoo.forestmanager.ui.media;

import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.huicoo.forestmanager.R;
import com.huicoo.forestmanager.others.MediaEvent;
import com.huicoo.forestmanager.util.AttachmentHelper;
import com.huicoo.forestmanager.util.LogUtils;

import org.greenrobot.eventbus.EventBus;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class TakePhotoActivity extends AppCompatActivity implements View.OnClickListener {
    private Camera mCamera;
    private TextView tv_confirm;
    private RelativeLayout rl_shot;
    private ViewGroup rl_sure;

    private int mOrientation;
    private String FolderPath;
    private byte[] data;

    private boolean takeDone = false;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getSupportActionBar() != null) {
            getSupportActionBar().hide();
        }
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        setContentView(R.layout.activity_take_photo);

        initView();

        FolderPath = AttachmentHelper.rootPath;
        File path = new File(FolderPath);
        if (!path.exists()) {
            path.mkdirs();
        }
    }

    private void initView() {
        rl_shot = findViewById(R.id.rl_shot);
        rl_sure = findViewById(R.id.rl_sure);
        TextView tv_reset = findViewById(R.id.tv_reset);
        tv_confirm = findViewById(R.id.tv_confirm);

        mOrientation = cameraDisplayOrientation();

        mCamera = Camera.open();    //初始化 Camera对象
        mCamera.setDisplayOrientation(mOrientation);
        CameraPreview mPreview = new CameraPreview(this, mCamera);
        FrameLayout camera_preview = findViewById(R.id.camera_preview);
        camera_preview.addView(mPreview);

        rl_shot.setOnClickListener(this);
        tv_reset.setOnClickListener(this);
        tv_confirm.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.rl_shot:
                startShot();
                break;
            case R.id.tv_reset:
                mCamera.startPreview();
                rl_shot.setVisibility(View.VISIBLE);
                rl_sure.setVisibility(View.GONE);
                break;
            case R.id.tv_confirm:
                takeSuccess();
                break;
            default:
                break;
        }
    }

    private void startShot() {
        //得到照相机的参数
        Camera.Parameters parameters = mCamera.getParameters();
        try {
            //图片的格式
            parameters.setPictureFormat(ImageFormat.JPEG);
            //预览的大小是多少
            Camera.Size size = parameters.getPreviewSize();
            LogUtils.v("gogogo default size = " + size.width + "  --  " + size.height);
            if (size.width < 1920) {
                Camera.Size fineSize = getPreviewSize(parameters.getSupportedPreviewSizes());
                if (fineSize != null) {
                    LogUtils.v("gogogo fine size = " + fineSize.width + "  --  " + fineSize.height);
                    parameters.setPreviewSize(fineSize.width, fineSize.height);
                    parameters.setPictureSize(fineSize.width, fineSize.height);
                }
                mCamera.setParameters(parameters);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        //设置对焦模式，自动对焦
        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
        //对焦成功后，自动拍照
        mCamera.autoFocus(new Camera.AutoFocusCallback() {
            @Override
            public void onAutoFocus(boolean success, Camera camera) {
                if (success) {
                    //获取照片
                    mCamera.takePicture(null, null, mPictureCallback);
                }
            }
        });
        mCamera.setParameters(parameters);
    }

    //获取照片中的接口回调
    Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            TakePhotoActivity.this.data = data;
            Log.v("ForestManager", "gogogo picture success");
            rl_shot.setVisibility(View.GONE);
            rl_sure.setVisibility(View.VISIBLE);
        }
    };

    private void takeSuccess() {
        if (data == null || data.length <= 0) {
            return;
        }
        tv_confirm.setEnabled(false);

        Bitmap thumb = BitmapFactory.decodeByteArray(data, 0, data.length);
        Matrix matrix = new Matrix();
        matrix.postRotate(mOrientation);
        Bitmap newThumb = Bitmap.createBitmap(thumb, 0, 0, thumb.getWidth(), thumb.getHeight(), matrix, true);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        newThumb.compress(Bitmap.CompressFormat.JPEG, 50, baos);
        FileOutputStream fos = null;
        String mFilePath = FolderPath + System.currentTimeMillis() + ".jpg";
        //文件
        File tempFile = new File(mFilePath);
        try {
            tempFile.createNewFile();
            fos = new FileOutputStream(tempFile);
            InputStream is = new ByteArrayInputStream(baos.toByteArray());
            int x = 0;
            byte[] b = new byte[1024 * 100];
            while ((x = is.read(b)) != -1) {
                fos.write(b, 0, x);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        EventBus.getDefault().post(new MediaEvent(2, mFilePath));
        takeDone = true;
        finish();
    }

    //根据当前界面显示方向设置摄像头预览方向
    public int cameraDisplayOrientation() {
        Camera.CameraInfo info = new Camera.CameraInfo();
        Camera.getCameraInfo(0, info);
        int rotation = this.getWindowManager().getDefaultDisplay().getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break;
            case Surface.ROTATION_90:
                degrees = 90;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
        }

        int result;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360;
        } else {
            result = (info.orientation - degrees + 360) % 360;
        }
        //返回需要旋转的角度
        return result;
    }

    //获取相机最佳尺寸
    private Camera.Size getPreviewSize(List<Camera.Size> list) {
        Camera.Size selectSize = null;

        if (list.size() >= 1) {
            for (Camera.Size cur : list) {
                if (cur.width == 1920 && cur.height == 1080) {
                    selectSize = cur;
                    break;
                }
            }
        }

        return selectSize;
    }

    @Override
    protected void onDestroy() {
        if (!takeDone) {
            EventBus.getDefault().post(new MediaEvent(2, null));
        }
        super.onDestroy();
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.setPreviewCallback(null);
            mCamera.release();
            mCamera = null;
        }
    }
}
